package com.yunwaikeji.gy_tool_library.utils;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.text.ClipboardManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.yunwaikeji.gy_tool_library.utils.display.GYDisplayUtils;
import com.yunwaikeji.gy_tool_library.widget.GYEditText;
import com.yunwaikeji.gy_tool_library.view.GYTextView;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * by 郭杨 on 2018/12/07
 * 工具类
 */
public class GYUtils {
    /**
     * 压缩图片
     * 该方法引用自：http://blog.csdn.net/demonliuhui/article/details/52949203
     *
     * @param image
     * @return
     */
    public static Bitmap compressImage(Bitmap image) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length / 1024 > 100) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();//重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%，把压缩后的数据存放到baos中
            options -= 10;//每次都减少10
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
        return bitmap;
    }

    /**
     * 判断是否有网络
     *
     * @param context
     * @return
     */
    public static boolean isNetworkConnected(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
            if (mNetworkInfo != null) {
                return mNetworkInfo.isAvailable();
            }
        }
        return false;
    }

    /**
     * 判断Wifi网络是否可用
     *
     * @param context
     * @return
     */
    public static boolean isWifiConnected(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mWiFiNetworkInfo = mConnectivityManager
                    .getNetworkInfo(ConnectivityManager.TYPE_WIFI);
            if (mWiFiNetworkInfo != null) {
                return mWiFiNetworkInfo.isAvailable();
            }
        }
        return false;
    }

    /**
     * 判断Mobile网络是否可用
     *
     * @param context
     * @return
     */
    public static boolean isMobileConnected(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mMobileNetworkInfo = mConnectivityManager
                    .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
            if (mMobileNetworkInfo != null) {
                return mMobileNetworkInfo.isAvailable();
            }
        }
        return false;
    }

    /**
     * 获取当前网络连接的类型信息
     *
     * @param context
     * @return
     */
    public static int getConnectedType(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
            if (mNetworkInfo != null && mNetworkInfo.isAvailable()) {
                return mNetworkInfo.getType();
            }
        }
        return -1;
    }

    /**
     * 转金额
     *
     * @return
     */
    public static String toMoney(BigDecimal bigDecimal) {
        if (bigDecimal == null) {
            return "0.00";
        }
        return bigDecimal.setScale(2, BigDecimal.ROUND_DOWN).toString();
    }

    /**
     * 转金额
     *
     * @param s
     * @return
     */
    public static String toMoney(String s) {
        if (TextUtils.isEmpty(s)) {
            s = "0.00";
        }
        BigDecimal bigDecimal = new BigDecimal(s);
        return bigDecimal.setScale(2, BigDecimal.ROUND_DOWN).toString();
    }

    /**
     * 转整数
     *
     * @param s
     * @return
     */
    public static String toIntString(String s) {
        if (TextUtils.isEmpty(s)) {
            s = "0";
        }
        BigDecimal bigDecimal = new BigDecimal(s);
        return bigDecimal.setScale(0, BigDecimal.ROUND_DOWN).toString();
    }

    /**
     * 转整数
     *
     * @param object
     * @return
     */
    public static String toIntString(Object object) {
//        if (TextUtils.isEmpty(object)) {
//            s = "0";
//        }
        BigDecimal bigDecimal = new BigDecimal(String.valueOf(object));
        return bigDecimal.setScale(0, BigDecimal.ROUND_DOWN).toString();
    }

    /**
     * 转整数
     *
     * @param object
     * @return
     */
    public static int toInt(Object object) {
//        if (TextUtils.isEmpty(object)) {
//            s = "0";
//        }
        BigDecimal bigDecimal = new BigDecimal(String.valueOf(object));
        return Integer.valueOf(bigDecimal.setScale(0, BigDecimal.ROUND_DOWN).toString());
    }

    /**
     * 转整数
     *
     * @param s
     * @return
     */
    public static int toInt(String s) {
        if (TextUtils.isEmpty(s)) {
            s = "0";
        }
        BigDecimal bigDecimal = new BigDecimal(s);
        return Integer.valueOf(bigDecimal.setScale(0, BigDecimal.ROUND_DOWN).toString());
    }

    /**
     * 转金额
     *
     * @param i
     * @return
     */
    public static String toMoney(int i) {
        return new BigDecimal(i).setScale(2, BigDecimal.ROUND_DOWN).toString();
    }

    /**
     * 转金额
     *
     * @param d
     * @return
     */
    public static String toMoney(double d) {
        return new BigDecimal(d).setScale(2, BigDecimal.ROUND_DOWN).toString();
    }

    /**
     * 转整数
     *
     * @param d
     * @return
     */
    public static int toInt(double d) {
        return Integer.parseInt(new BigDecimal(d).setScale(0, BigDecimal.ROUND_DOWN).toString());
    }

    public static String toDecimal2(BigDecimal bigDecimal) {
        return toDecimal(bigDecimal, 2);
    }

    public static String toDecimal(BigDecimal bigDecimal, int pointCount) {
        return toDecimal(bigDecimal, pointCount, BigDecimal.ROUND_DOWN);
    }

    public static String toDecimal(BigDecimal bigDecimal, int pointCount, int roundingMode) {
        if (bigDecimal == null) {
            bigDecimal = new BigDecimal(0);
        }
        return bigDecimal.setScale(pointCount, roundingMode).toString();
    }

    /**
     * 拨打电话（直接拨打电话）
     * 权限：<uses-permission android:name="android.permission.CALL_PHONE" />
     *
     * @param context
     * @param phoneNum 电话号码
     */
    @SuppressLint("MissingPermission")
    public static void callPhone(Context context, String phoneNum) {
        try {
            Intent intent = new Intent(Intent.ACTION_CALL);
            Uri data = Uri.parse("tel:" + phoneNum);
            intent.setData(data);
            context.startActivity(intent);
        } catch (Exception e) {
        }
    }

    /**
     * 拨打电话（跳转到拨号界面，用户手动点击拨打）
     * 权限：<uses-permission android:name="android.permission.CALL_PHONE" />
     *
     * @param context
     * @param phoneNum 电话号码
     */
    public static void callPhoneToNumber(Context context, String phoneNum) {
        try {
            Intent intent = new Intent(Intent.ACTION_DIAL);
            Uri data = Uri.parse("tel:" + phoneNum);
            intent.setData(data);
            context.startActivity(intent);
        } catch (Exception e) {

        }
    }

    public static void showToast(Context context, String showString, int duration) {
        if (context != null) {
            Toast.makeText(context, showString, duration).show();
        }
    }

    /**
     * 显示提示信息
     *
     * @param context
     * @param showString
     */
    public static void showToastLong(Context context, String showString) {
        showToast(context, showString, Toast.LENGTH_LONG);
    }

    /**
     * 显示提示信息
     *
     * @param context
     * @param showString
     */
    public static void showToastShort(Context context, String showString) {
        showToast(context, showString, Toast.LENGTH_SHORT);
    }

    /**
     * 获取屏幕宽度
     *
     * @param context
     * @return
     */
    public static int getWindowWidth(Context context) {
        WindowManager windowManager = scanForActivity(context).getWindow().getWindowManager();
        Display display = windowManager.getDefaultDisplay();//为获取屏幕宽和高
        return display.getWidth();
    }

    /**
     * 获取屏幕高度
     *
     * @param context
     * @return
     */
    public static int getWindowHeight(Context context) {
        WindowManager windowManager = scanForActivity(context).getWindow().getWindowManager();
        Display display = windowManager.getDefaultDisplay();//为获取屏幕宽和高
        return display.getHeight();
    }

    public static int getWindowWidth(Context context, float proportion) {
        return (int) (getWindowWidth(context) * proportion);
    }

    public static int getWindowHeight(Context context, float proportion) {
        return (int) (getWindowHeight(context) * proportion);
    }

    /**
     * 获取view在父窗口的X坐标
     *
     * @param view
     * @return
     */
    public static int getLocationWindowX(View view) {
        int[] location = new int[2];
        view.getLocationInWindow(location);
        return location[0];
    }

    /**
     * 获取view在父窗口的Y坐标
     *
     * @param view
     * @return
     */
    public static int getLocationWindowY(View view) {
        int[] location = new int[2];
        view.getLocationInWindow(location);
        return location[1];
    }

    /**
     * 获取view在整个 屏幕 的X坐标
     *
     * @param view
     * @return
     */
    public static int getLocationScreenX(View view) {
        int[] location = new int[2];
        view.getLocationOnScreen(location);
        return location[0];
    }

    /**
     * 获取view在整个 屏幕 的Y坐标
     *
     * @param view
     * @return
     */
    public static int getLocationScreenY(View view) {
        int[] location = new int[2];
        view.getLocationOnScreen(location);
        return location[1];
    }

    /**
     * 设置添加屏幕的背景透明度
     *
     * @param bgAlpha
     */
    public void setBackgroundAlpha(Context context, float bgAlpha) {
        Activity activity = scanForActivity(context);
        WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
        lp.alpha = bgAlpha; //0.0-1.0
        activity.getWindow().setAttributes(lp);
        activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
    }

    /**
     * 将unicode的汉字码转换成utf-8格式的汉字
     *
     * @param unicode
     * @return
     */
    public static String unicodeToUTF8(String unicode) {
        String str = unicode.replace("0x", "\\");
        StringBuffer string = new StringBuffer();
        String[] hex = str.split("\\\\u");
        for (int i = 1; i < hex.length; i++) {
            int data = Integer.parseInt(hex[i], 16);
            string.append((char) data);
        }
        return string.toString();
    }

    /**
     * 动态设置字体大小
     *
     * @param context
     * @param textView
     * @param width
     */
    public static void setTextSize(Context context, TextView textView, int width) {
        textView.setTextSize((textView.getTextSize() * GYUtils.getWindowWidth(context)) / width);
    }

    /**
     * 动态设置字体大小
     *
     * @param context
     * @param editText
     * @param width
     */
    public static void setTextSize(Context context, EditText editText, int width) {
        editText.setTextSize((editText.getTextSize() * GYUtils.getWindowWidth(context)) / width);
    }

    /**
     * 读取指定目录下的所有TXT文件的文件内容
     *
     * @param fileString
     * @return
     */
    public static String readerSDTxt(String fileString) {
        StringBuilder content = new StringBuilder();
        File file = new File(fileString);
        if (!file.isDirectory()) {  //检查此路径名的文件是否是一个目录(文件夹)
            if (file.getName().endsWith("txt")) {//文件格式为""文件
                try {
                    InputStream instream = new FileInputStream(file);
                    InputStreamReader inputreader
                            = new InputStreamReader(instream, StandardCharsets.UTF_8);
                    BufferedReader buffreader = new BufferedReader(inputreader);
                    String line = "";
                    //分行读取
                    while ((line = buffreader.readLine()) != null) {
                        content.append(line).append("\n");
                    }
                    instream.close();//关闭输入流
                } catch (FileNotFoundException e) {
                    Log.d("TestFile", "The File doesn't not exist.");
                } catch (IOException e) {
                    Log.d("TestFile", e.getMessage());
                }
            }
        }
        return content.toString();
    }

    /**
     * 是否存在浏览器
     *
     * @param context
     * @return
     */
    public static boolean hasBrowser(Context context) {
        String url = "http://www.google.com";
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        List<ResolveInfo> list = context.getPackageManager().queryIntentActivities(intent, 0);
        return list.size() > 0;
    }

    public static JsonObject javaBeanToJsonObject(Object object) {
        if (object == null || object.toString().length() == 0) {
            return null;
        }
        Gson gson = new Gson();
        return new JsonParser().parse(gson.toJson(object)).getAsJsonObject();
    }

    public static JsonArray javaBeanListToJsonArray(List list) {
        if (list == null) {
            return null;
        }
        Gson gson = new Gson();
        return new JsonParser().parse(gson.toJson(list)).getAsJsonArray();
    }

    public static Map javaBeanToMap(Object object) {
        if (object == null || object.toString().length() == 0) {
            return null;
        }
        JsonObject jsonObject = javaBeanToJsonObject(object);
        Map map = new HashMap();
        for (String string : jsonObject.keySet()) {
            if (!jsonObject.get(string).getAsString().equals("0")) {
                map.put(string, jsonObject.get(string).getAsString());
            }
        }
        return map;
    }

    /**
     * 复制信息到系统剪切板
     *
     * @param context
     * @param text
     */
    public static void copyToSystem(Context context, String text) {
        ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
        assert clipboardManager != null;
        clipboardManager.setText(text);
    }

    /**
     * 复制TextView信息到系统剪切板
     *
     * @param context
     * @param textView
     */
    public static void copyToSystem(Context context, TextView textView) {
        ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
        clipboardManager.setText(textView.getText());
    }

    public static void copyToSystem(Context context, TextView textView, String tips) {
        ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
        clipboardManager.setText(textView.getText());
        showToastLong(context, tips);
    }

    /**
     * 补齐长度位数
     *
     * @param number 原始int
     * @param count  最短长度
     * @return
     */
    public static String toDigit(String number, int count) {
        StringBuilder string = new StringBuilder();
        if (number.length() < count) {
            for (int i = 0; i < (count - number.length()); i++) {
                string.append("0");
            }
        }
        string.append(number);
        return string.toString();
    }

    public static String toDigit(int number, int count) {
        return toDigit(String.valueOf(number), count);
    }

    public static String nullToString(String string) {
        return TextUtils.isEmpty(string) ? "" : string;
    }

    /**
     * context转activity
     *
     * @param context
     * @return
     */
    public static Activity scanForActivity(Context context) {
        if (context == null) {
            return null;
        } else if (context instanceof Activity) {
            return (Activity) context;
        } else if (context instanceof ContextWrapper) {
            return scanForActivity(((ContextWrapper) context).getBaseContext());
        }
        return null;
    }

    /**
     * 验证是否为手机号
     * 2020-11-20
     *
     * @param phone
     * @return
     */
    public static boolean isPhone(String phone) {
        return isPhone(phone, "^1(3([0-35-9]\\d|4[1-8])|4[14-9]\\d|5([01235689]\\d|7[1-79])|6[67]\\d|7[0-35-8]\\d|8\\d{2}|9[13589]\\d)\\d{7}$");
    }

    public static boolean isPhone(String phone, String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(phone);
        return matcher.find();
    }

    /**
     * 设置光标颜色
     *
     * @param editText
     * @param color
     */
    public static void setCursorDrawableColor(GYEditText editText, int color) {
        try {
            Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");//获取这个字段
            fCursorDrawableRes.setAccessible(true);//代表这个字段、方法等等可以被访问
            int mCursorDrawableRes = fCursorDrawableRes.getInt(editText);

            Field fEditor = TextView.class.getDeclaredField("mEditor");
            fEditor.setAccessible(true);
            Object editor = fEditor.get(editText);

//            Class<?> clazz = editor.getClass();
//            Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable");
            Class<?> editorClazz = Class.forName("android.widget.Editor");
            Field fCursorDrawable = editorClazz.getDeclaredField("mCursorDrawable");

            fCursorDrawable.setAccessible(true);

//            Drawable[] drawables = new Drawable[2];
//            drawables[0] = editText.getContext().getResources().getDrawable(mCursorDrawableRes);
//            drawables[1] = editText.getContext().getResources().getDrawable(mCursorDrawableRes);
//            drawables[0].setColorFilter(color, PorterDuff.Mode.SRC_IN);//SRC_IN 上下层都显示。下层居上显示。
//            drawables[1].setColorFilter(color, PorterDuff.Mode.SRC_IN);
//            fCursorDrawable.set(editor, drawables);

            //根据光标的resid获取到相应的drawable
            Drawable cursorDrawable = editText.getContext().getResources().getDrawable(mCursorDrawableRes);
            if (cursorDrawable == null) {
                return;
            }
            //然后给cursorDrawable着色
            Drawable tintDrawable = GYDisplayUtils.tintDrawable(cursorDrawable, ColorStateList.valueOf(color));
            //把着色后的cursorDrawable给editor的mCursorDrawable数组
            Drawable[] drawables = new Drawable[]{tintDrawable, tintDrawable};
            fCursorDrawable.set(editor, drawables);
        } catch (Throwable ignored) {
            ignored.getMessage();
        }
    }

    /**
     * 设置光标样式
     *
     * @param editText
     * @param drawables
     */
    public static void setCursorDrawable(GYEditText editText, Drawable... drawables) {
        try {
            Field fCursorDrawableRes = GYTextView.class.getDeclaredField("mCursorDrawableRes");//获取这个字段
            fCursorDrawableRes.setAccessible(true);//代表这个字段、方法等等可以被访问

            Field fEditor = TextView.class.getDeclaredField("mEditor");
            fEditor.setAccessible(true);
            Object editor = fEditor.get(editText);

            Class<?> clazz = editor.getClass();
            Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable");
            fCursorDrawable.setAccessible(true);

            fCursorDrawable.set(editor, drawables);
        } catch (Throwable ignored) {
        }
    }

    /**
     * 判断是否为数字
     *
     * @param str
     * @return
     */
    public static boolean isNumber(String str) {
        if (TextUtils.isEmpty(str)) {
            return false;
        }
        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(str).matches();
    }

    /**
     * 判断是否包含中文
     *
     * @param content
     * @return
     */
    public static boolean hasChinese(String content) {
        Pattern pattern = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher matcher = pattern.matcher(content);
        return matcher.find();
    }

    /**
     * 判断是否为中文
     *
     * @param content
     * @return
     */
    public boolean isChinese(String content) {
        int n;
        for (int i = 0; i < content.length(); i++) {
            n = content.charAt(i);
            if (!(19968 <= n && n < 40869)) {
                return false;
            }
        }
        return true;
    }

    private static long finishActivityLastTime = 0;

    public static void onBackPressedFinishActivity(Activity activity, String tips) {
        long nowTime = System.currentTimeMillis();
        if ((nowTime - finishActivityLastTime) >= 2000) {
            finishActivityLastTime = nowTime;
            showToastLong(activity, tips);
        } else {
            activity.finish();
        }
    }

    public static void onBackPressedFinishActivity(Activity activity) {
        onBackPressedFinishActivity(activity, "再按一次退出程序");
    }

    public static boolean isNullOrEmpty(Integer integer) {
        return integer == null || integer == 0;
    }

    public static boolean isNullOrEmpty(CharSequence charSequence) {
        return TextUtils.isEmpty(charSequence);
    }
}
